package com.junt.library.view;

import android.os.Bundle;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.PopupWindow;

import com.junt.library.MediaSelector;
import com.junt.library.R;
import com.junt.library.adapter.DirAdapter;
import com.junt.library.model.Directory;
import com.junt.library.model.Media;
import com.junt.library.widgets.DirPopupView;
import com.junt.library.widgets.DropDownView;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 将媒体文件按目录进行划分
 */
public class DirectoryActivity extends BaseMediaActivity {
    private static final String TAG = "DirectoryActivity";

    public static final String DIR_RECENT = "最近项目";
    private FrameLayout flTitle;

    private Map<String, List<Media>> dirMap;
    private DirPopupView dirPopupView;
    private DropDownView dropDownView;
    private GridFragment gridFragment;

    @Override
    int getLayoutResId() {
        return R.layout.activity_directory;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void init() {
        dirMap = new LinkedHashMap<>();
        flTitle = findViewById(R.id.flTitle);
        findViewById(R.id.tvClose).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MediaSelector.getInstance().setNoneResult(DirectoryActivity.this);
            }
        });
        initDropDownView();
        initRecyclerView();
    }

    private void initDropDownView() {
        dropDownView = findViewById(R.id.dropDir);
        dropDownView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    dirPopupView.showAsDropDown(flTitle);
                } else {
                    dirPopupView.dismiss();
                }
            }
        });
    }

    private void initRecyclerView() {
        gridFragment = GridFragment.newInstance(MediaSelector.getInstance().getQueryType().ordinal());
        getSupportFragmentManager().beginTransaction().add(R.id.flGrid, gridFragment).commit();
    }

    @Override
    protected void onDataReady(List<Media> medias) {
        classify(medias);
        setUpDirPopup();
        setOriginalData();
    }

    /**
     * set data when activity is launched
     */
    private void setOriginalData() {
        if (dirMap.keySet().size() > 0) {
            if (dirMap.containsKey(DIR_RECENT)) {
                dropDownView.setText(DIR_RECENT);
                setNewData(dirMap.get(DIR_RECENT));
            } else {
                for (Map.Entry<String, List<Media>> entry : dirMap.entrySet()) {
                    dropDownView.setText(entry.getKey());
                    setNewData(entry.getValue());
                    break;
                }
            }
        }
    }

    /**
     * set new data
     *
     * @param medias medias
     */
    private void setNewData(List<Media> medias) {
        gridFragment.setNewData(medias);
    }

    private void setUpDirPopup() {
        dirPopupView = new DirPopupView(this, flTitle.getWidth(), new DirAdapter.OnDirectorySelectedListener() {
            @Override
            public void onDirSelected(Directory directory) {
                dropDownView.setText(directory.getText());
                setNewData(dirMap.get(directory.getText()));
                dropDownView.setDrop(false);
                dirPopupView.dismiss();
            }

            @Override
            public String getSelectedDir() {
                return dropDownView.getText();
            }
        });
        dirPopupView.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                dropDownView.setDrop(false);
            }
        });
        dirPopupView.setDirMap(dirMap);
    }

    /**
     * Classify the medias into different directories.
     *
     * @param medias medias
     */
    private void classify(List<Media> medias) {
        for (Media media : medias) {
            String dir = getParentPath(media.getRelativePath(), media.getAbsolutePath());
            // if this media is modified recently，add it to the recent directory.
            // if field dateModified is null,then use the field dateAdded.
            long modifiedDate = ((media.getDateModified() == 0 ? (media.getDateAdded()) : media.getDateModified()));
            if (isModifiedRecently(modifiedDate)) {
                if (dirMap.containsKey(DIR_RECENT)) {
                    dirMap.get(DIR_RECENT).add(media);
                } else {
                    List<Media> list = new ArrayList<>();
                    list.add(media);
                    dirMap.put(DIR_RECENT, list);
                }
            }

            if (dirMap.containsKey(dir)) {
                dirMap.get(dir).add(media);
            } else {
                List<Media> list = new ArrayList<>();
                list.add(media);
                dirMap.put(dir, list);
            }
        }
    }

    /**
     * @param relativePath medias file's relativePath
     * @param absolutePath medias file's absolutePath
     * @return the media file's parent directory path
     */
    private String getParentPath(String relativePath, String absolutePath) {
        if (relativePath != null && relativePath.contains("/")) {
            String[] split = relativePath.split("/");
            if (split.length > 0) {
                return split[split.length - 1];
            }
        }
        if (absolutePath != null && absolutePath.contains("/")) {
            String[] split = absolutePath.split("/");
            if (split.length > 1) {
                return split[split.length - 2];
            }
        }
        return "其他";
    }

    /**
     * Is this media modified recently in 7 days
     *
     * @param dateModified last modified date
     * @return true - is modified recently false - is not modified recently
     */
    private boolean isModifiedRecently(long dateModified) {
        return (System.currentTimeMillis() / 1000 - dateModified) < 7 * 24 * 60 * 60;
    }
}